package com.lantosec.hmrp.modules.login.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lantosec.hmrp.core.kit.Result;
import com.lantosec.hmrp.core.kit.ResultEnum;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Title: Shiro访问权限控制 
 * Description: 解决前后端分离架构中的shiro未登录的问题
 *
 *
 */
public class TokenAuthenticationFilter extends FormAuthenticationFilter {

    /**
	 * 屏蔽OPTIONS请求
	 */
	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
		boolean accessAllowed = super.isAccessAllowed(request, response, mappedValue);
		if (!accessAllowed) {
			// 判断请求是否是options请求
			String method = WebUtils.toHttp(request).getMethod();
			if (RequestMethod.OPTIONS.name().equals(method)) {
				return true;
			}
		}
		return accessAllowed;
	}
 
	/**
	 * 解决未登录302问题
	 */
	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
		if (isLoginRequest(request, response)) {
			if (isLoginSubmission(request, response)) {
				return executeLogin(request, response);
			} else {
				return true;
			}
		} else {
			unauthentication(response);
			return false;
		}
	}
	
	/**
	 * 未登录返回尚未登录信息
	 * @param response
	 * @throws IOException
	 */
	private void unauthentication(ServletResponse response) throws IOException {
		HttpServletResponse httpResponse = WebUtils.toHttp(response);
		httpResponse.setStatus(HttpServletResponse.SC_OK);
		httpResponse.setContentType("application/json;charset=utf-8");
		httpResponse.setCharacterEncoding("utf-8");
		ObjectMapper objectMapper = new ObjectMapper();
		String jsonResult = objectMapper.writeValueAsString(Result.by(ResultEnum.IDENTIFY_FAILURE));//尚未登录，请先登录
		httpResponse.getWriter().write(jsonResult);
		httpResponse.getWriter().flush();
	}
}